namespace MicroCloud.CodeGenerator.Views.Entities
{
    [Singleton]
    public class ForeignListViewModel : Screen
    {
        private readonly IServiceProvider _provider;

        public ForeignListViewModel(IServiceProvider provider)
        {
            _provider = provider;
        }

        public bool IsShow { get; set; }

        public string Title { get; set; }

        public IObservableCollection<ForeignViewModel> Foreigns { get; set; } = new BindableCollection<ForeignViewModel>();

        public EntityViewModel Entity { get; set; }

        public IObservableCollection<string> SelfNavigations
        {
            get
            {
                string[] props = GetProperties()?.Where(a => a.IsNavigation)
                    .Select(a => a.Name).ToArray();
                return new BindableCollection<string>(props);
            }
        }

        public IObservableCollection<string> SelfForeignKeys
        {
            get
            {
                string[] props = GetProperties()?.Where(a => a.IsForeignKey)
                    .Select(a => a.Name).ToArray();
                return new BindableCollection<string>(props);
            }
        }

        public IObservableCollection<string> OtherEntities
        {
            get
            {
                string[] entities = ViewModelLocator.Instance.Entities;
                return new BindableCollection<string>(entities);
            }
        }

        public ForeignRelation[] ForeignRelations
        {
            get
            {
                return ViewModelLocator.Instance.ForeignRelations;
            }
        }

        public DeleteBehavior?[] DeleteBehaviors
        {
            get
            {
                return ViewModelLocator.Instance.DeleteBehaviors;
            }
        }

        public void Init()
        {
            CodeForeign[] foreigns = new CodeForeign[0];
            _provider.ExecuteScopedWork(provider =>
            {
                IDataContract contract = provider.GetRequiredService<IDataContract>();
                foreigns = contract.CodeForeigns.Where(m => m.EntityId == Entity.Id).ToArray();
            });
            Foreigns.Clear();
            foreach (CodeForeign foreign in foreigns)
            {
                ForeignViewModel model = _provider.GetRequiredService<ForeignViewModel>();
                model = foreign.MapTo(model);
                Foreigns.Add(model);
            }
        }

        public void New()
        {
            ForeignViewModel model = IoC.Get<ForeignViewModel>();
            model.EntityId = Entity.Id;
            Foreigns.Add(model);
        }

        public bool CanSave => Foreigns.All(m => !m.HasErrors);
        public async void Save()
        {
            if (!CanSave)
            {
                Helper.Notify("实体外键信息验证失败", NotificationType.Warning);
                return;
            }

            CodeForeignInDto[] dtos = Foreigns.Select(m => m.MapTo<CodeForeignInDto>()).ToArray();
            OperationResult result = null;
            await _provider.ExecuteScopedWorkAsync(async provider =>
            {
                IDataContract contract = provider.GetRequiredService<IDataContract>();
                result = await contract.UpdateCodeForeigns(dtos);
            });
            Helper.Notify(result);
            if (!result.Succeeded)
            {
                return;
            }

            Init();
        }

        private CodeProperty[] GetProperties()
        {
            CodeProperty[] props = new CodeProperty[0];
            _provider.ExecuteScopedWork(provider =>
            {
                IDataContract contract = provider.GetRequiredService<IDataContract>();
                props = contract.CodeProperties.Where(m => m.EntityId == Entity.Id).ToArray();
            });
            return props;
        }
    }
}
